import { UseGuards, createParamDecorator, ExecutionContext, applyDecorators, SetMetadata } from "@nestjs/common";
import { UserRole } from "src/modules/user/user.interface";
import { AUTH_ADMIN_META_KEY } from "./auth.constant";
import { BasicGuard } from "./guard/basic/auth.basic.guard";
import { JwtRefreshGuard } from "./guard/jwt-refresh/auth.jwt-refresh.guard";
import { JwtGuard } from "./guard/jwt/auth.jwt.guard";
import { AuthPayloadAdminGuard } from "./guard/payload/auth.payload.admin.guard";
import { AuthPayloadDefaultGuard } from "./guard/payload/auth.payload.default.guard";

export function AuthAdminJwtGuard(roles: UserRole[] = []) {
  return applyDecorators(
    UseGuards(JwtGuard, AuthPayloadDefaultGuard, AuthPayloadAdminGuard),
    SetMetadata(AUTH_ADMIN_META_KEY, roles.concat([UserRole.ROLE_ADMIN]))
  );
}

export function AuthJwtGuard(): any {
  return applyDecorators(UseGuards(JwtGuard, AuthPayloadDefaultGuard));
}

export function AuthRefreshJwtGuard(): any {
  return applyDecorators(UseGuards(JwtRefreshGuard));
}

export function AuthBasicGuard(): any {
  return applyDecorators(UseGuards(BasicGuard));
}

export const User = createParamDecorator((data: string, ctx: ExecutionContext): Record<string, any> => {
  const { user } = ctx.switchToHttp().getRequest();
  return data ? user[data] : user;
});

export const Token = createParamDecorator((data: string, ctx: ExecutionContext): string => {
  const { headers } = ctx.switchToHttp().getRequest();
  const { authorization } = headers;
  return authorization ? authorization.split(" ")[1] : undefined;
});
